/**
 * 
 */
package com.google.code.maven.plugin.http.client.transformer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

/**
 * ResponseFileTransformer
 * 
 * @author Nadim Benabdenbi
 * @version 1.0
 * @since JDK1.5
 * 
 * @see AbstractHttpEntityTransformer
 */
public class BufferedReaderResourceWriter extends AbstractTransformer<BufferedReader, Resource> {

	/**
	 * the output file
	 * 
	 * @parameter
	 */
	private Resource output;

	/**
	 * overwrite indicator
	 * 
	 * @parameter
	 */
	private boolean overwrite;

	/**
	 * the file encoding
	 * 
	 * @parameter
	 */
	private String encoding;

	/**
	 * default constructor
	 */
	public BufferedReaderResourceWriter() {
		this(new FileSystemResource("target/generated-site/http-response.html"), true, Charset.defaultCharset().name());
	}

	/**
	 * output constructor
	 * 
	 * @param output
	 */
	public BufferedReaderResourceWriter(Resource output) {
		this(output, true, Charset.defaultCharset().name());
	}

	/**
	 * all fields constructor
	 * 
	 * @param output
	 * @param overwrite
	 * @param encoding
	 */
	public BufferedReaderResourceWriter(Resource output, boolean overwrite, String encoding) {
		super();
		this.output = output;
		this.overwrite = overwrite;
		this.encoding = encoding;
	}

	/**
	 * 
	 */
	@Override
	public Resource doTransform(BufferedReader reader) throws IOException {
		log.info("writing source to [" + output + "] ...");
		Assert.notNull(output, "output file could not be null");
		if (output.getFile().getParentFile() != null && !output.getFile().getParentFile().exists()) {
			Assert.isTrue(output.getFile().getParentFile().mkdirs(), "failed to make directory tree for [" + output.getFile().getParentFile() + "]");
		}
		File file = output.getFile();
		Assert.isTrue(!file.exists() || overwrite, "file exists consider overwrite option [" + file + "]");
		if (output.getFile().getParentFile() != null && !output.getFile().getParentFile().exists()) {
			Assert.isTrue(file.getParentFile().mkdirs(), "failed to create directory tree");
		}
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
		char[] buffer = new char[DEFAULT_BUFFER_SIZE];
		int size;
		while ((size = reader.read(buffer)) > 0) {
			writer.write(buffer, 0, size);
			writer.flush();
		}
		reader.close();
		writer.close();
		log.info("source writed to [" + output + "].");
		return output;
	}

	/**
	 * output getter
	 * 
	 * @return the output
	 */
	public Resource getOutput() {
		return output;
	}

	/**
	 * output setter
	 * 
	 * @param output the output to set
	 */
	public void setOutput(Resource output) {
		Assert.notNull(output, "output file could not be null");
		this.output = output;
	}

	/**
	 * overwrite getter.
	 * 
	 * @return the overwrite
	 */
	public boolean isOverwrite() {
		return overwrite;
	}

	/**
	 * overwrite setter.
	 * 
	 * @param overwrite the overwrite to set
	 */
	public void setOverwrite(boolean overwrite) {
		this.overwrite = overwrite;
	}

	/**
	 * encoding getter.
	 * 
	 * @return the encoding
	 */
	public String getEncoding() {
		return encoding;
	}

	/**
	 * encoding setter.
	 * 
	 * @param encoding the encoding to set
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

}
